最小化簇内平方和(SSE):
\[SSE = \sum_{i=1}^{K}\sum_{x \in C_i} ||x - \mu_i||^2\]
# 注:case3.1.xlsx数据文件本地没有,但平台已经内置
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
import pandas as pd # 导入Pandas数据分析库
from sklearn.cluster import KMeans # 导入Scikit-learn的KMeans模块
import matplotlib.pyplot as plt # 导入Matplotlib绑图库
data = pd.read_excel("case3.1.xlsx") # 从Excel文件读取数据存入data
SSE = [] # 定义列表SSE
cols = data.iloc[:, 2:] # 提取数值型特征列(跳过前两列的非数值信息)
for k in range(1,10): # 遍历range(1,10)中的每个k
estimator = KMeans(n_clusters=k) # 初始化K-Means聚类模型
estimator.fit(cols) # 在数据上训练estimator模型
SSE.append(estimator.inertia_) # 将当前K值的簇内误差平方和(SSE)添加到列表
plt.plot(range(1,10), SSE,'*-') # 绑制折线图
plt.title('Elbow Method') # 设置图表标题
plt.xlabel('K Clusters') # 设置X轴标签
plt.ylabel('SSE') # 设置Y轴标签
plt.savefig("1.png") #过程展示一
data1=data.drop('股指',axis=1) # 删除指定行或列
clu = KMeans(n_clusters=3,random_state=30) # 初始化K-Means聚类模型
clu.fit(data1) # 在数据上训练clu模型
label = clu.labels_ # 获取聚类模型对每个样本的簇标签
print(label)# 结果展示data.iloc[:, 2:]:提取第3列起的所有数值特征KMeans(n_clusters=k):创建K-Means模型estimator.inertia_:获取当前K值下的SSEdata.drop('股指', axis=1):删除非数值列KMeans(n_clusters=3, random_state=30):设定3个簇clu.labels_:获取每个股指的聚类标签# 注:该代码块依赖的数据来自上方平台任务代码块,因其未执行,本块也无法执行
# ==================== 准备聚类特征数据 ====================
data_features = data.drop('股指', axis=1) # 删除非数值列'股指',axis=1表示按列删除
# 只保留数值型特征用于聚类分析
# ==================== 执行K-Means聚类 ====================
kmeans = KMeans(n_clusters=3, random_state=30) # 创建K-Means模型,设置聚类数为3
# random_state=30设置随机种子,与之前不同会得到不同的初始质心
kmeans.fit(data_features) # 在数据上拟合K-Means模型
# ==================== 获取聚类结果 ====================
labels = kmeans.labels_ # 获取每个样本的聚类标签(0, 1, 2)
# labels_属性存储了每个数据点所属的簇编号
# ==================== 获取聚类质心 ====================
centroids = kmeans.cluster_centers_ # 获取每个簇的质心坐标
# cluster_centers_属性存储了K个质心的位置
# ==================== 将聚类标签添加到原数据 ====================
data['Cluster'] = labels # 在原数据中新增Cluster列,存储聚类结果
# 这样可以方便地按簇进行后续分析
print('聚类标签:') # 输出标题
print(labels) # 显示每个样本的聚类标签
print('\n各簇样本数:') # 输出标题
print(pd.Series(labels).value_counts().sort_index()) # 统计每个簇的样本数
# pd.Series(labels).value_counts()统计每个标签出现的次数
# sort_index()按簇编号排序,使输出更清晰
print('\n聚类质心:') # 输出标题
for i, centroid in enumerate(centroids): # 遍历每个簇的质心
print(f'\n簇{i}质心:') # 输出簇编号
for j, value in enumerate(centroid): # 遍历质心的每个维度
print(f' 特征{j+1}: {value:.4f}') # 输出每个特征维度的质心坐标,保留4位小数kmeans.labels_:每个样本的簇标签(0、1、2)kmeans.cluster_centers_:每个簇的质心坐标# 注:该代码块依赖的数据来自上方平台任务代码块,因其未执行,本块也无法执行
# ==================== 按簇统计特征均值 ====================
cluster_stats = data.groupby('Cluster').mean() # 按簇分组,计算各特征的平均值
print('各簇平均特征:') # 输出标题
print(cluster_stats) # 显示每个簇的特征均值
# 这有助于理解每个簇的特点和商业含义
# ==================== 可视化聚类结果 ====================
plt.figure(figsize=(10, 6)) # 创建10x6英寸的画布
scatter = plt.scatter(
data_features.iloc[:, 0], # x轴为第1个特征
data_features.iloc[:, 1], # y轴为第2个特征
c=labels, # 颜色由聚类标签决定
cmap='viridis', # 使用viridis配色方案
s=100, # 散点大小为100
alpha=0.6 # 透明度为0.6
)
plt.colorbar(scatter, label='Cluster') # 添加颜色条,显示簇编号
plt.scatter(
centroids[:, 0], # 质心的x坐标
centroids[:, 1], # 质心的y坐标
c='red', # 质心颜色为红色
marker='X', # 质心标记为X形
s=300, # 质心大小为300
linewidths=2, # 边框线宽为2
edgecolors='black', # 边框颜色为黑色
label='质心' # 图例标签
)
plt.title('K-Means聚类结果', fontsize=14) # 设置图表标题
plt.xlabel('特征1', fontsize=12) # 设置x轴标签
plt.ylabel('特征2', fontsize=12) # 设置y轴标签
plt.legend() # 显示图例
plt.grid(True, alpha=0.3) # 显示网格线
plt.tight_layout() # 自动调整布局
plt.show() # 显示图表plt.scatter(... c=labels ...):用聚类标签着色plt.colorbar:添加颜色条,直观显示簇编号| 应用场景 | 说明 |
|---|---|
| 股票分类 | 根据波动率、收益率等特征分组 |
| 客户分层 | 作为RFM模型之外的补充手段 |
| 风险分组 | 识别高风险投资组合 |
| 异常检测 | 远离所有质心的数据点可能是异常 |
[商业大数据分析与应用]